package cacheEntity

import (
	"encoding/json"
	"github.com/bighuangbee/gokit/cache"
	"time"
)

const EXPIRE_DEFAULT = 60 * 60 //过期时间 s

type Client struct {
	Engine      cache.Cache
	EntityQuery entityQuery
	Policy      Policy
	Expire      time.Duration
	CacheKey    string
}

func New(engine cache.Cache, key string, opt ...Option) *Client {
	if engine == nil || key == ""{
		return nil
	}

	client := &Client{Engine: engine, CacheKey: key}
	for _, o := range opt{
		o(client)
	}
	return client
}

func(this *Client)SetEntityQuery(en entityQuery){
	this.EntityQuery = en
}

func(this *Client)Set(key string, val interface{}, options ...Option)error{
	for _, option := range options{
		option(this)
	}
	err := this.Engine.Set(key, val, this.Expire)
	if err != nil{
		return err
	}

	if this.Expire > 0{
		err = this.Engine.Expire(key, this.Expire)
		this.Expire = time.Second * EXPIRE_DEFAULT	//重置默认的过期时间
	}

	return err
}


func(this *Client)Get()interface{}{
	key := this.CacheKey
	val := this.Engine.Get(key)
	str, ok := val.(string)

	fn := func() interface{}{
		//实体查询结果为空时，必须返回nil
		val := this.EntityQuery()
		if val != nil {
			jsonVal, _ := json.Marshal(val)
			return string(jsonVal)
		}
		return nil
	}

	if ok && str == ""{
		if this.EntityQuery != nil{
			entityVal := fn()

			if entityVal == nil{
				if this.Policy != nil {
					this.Policy.SetHandle(this)
					this.Policy.Set(key, "")
				}
			}else{
				this.Set(key, entityVal)
				return entityVal
			}
		}
	}
	return val
}
